home *** CD-ROM | disk | FTP | other *** search
- /* @(#)src/smailconf.c 1.15 9/16/92 09:10:36 */
-
- /*
- * Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
- * Copyright (C) 1992 Ronald S. Karr
- *
- * See the file COPYING, distributed with smail, for restriction
- * and warranty information.
- */
-
- /*
- * smailconf.c:
- * loading and processing for the configuration files
- *
- * external functions: read_config_file, read_standard_file,
- * fill_attributes, find_attribute,
- * add_config_stat, is_newconf, make_lib_fn
- */
- #ifdef STANDALONE
- # ifdef scs
- # define void int
- # endif /* scs */
- #endif /* STANDALONE */
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "defs.h"
- #include "smail.h"
- #include "smailconf.h"
- #include "parse.h"
- #include "main.h"
- #include "exitcodes.h"
- #include "dys.h"
- #ifndef DEPEND
- # include "extern.h"
- # include "debug.h"
- #endif
-
- /* functions local to this file */
- static void print_config_help();
- static void print_config_all();
- static void print_version_banner();
-
- /* types local to this file */
- /*
- * config_stat_list is used by add_config_stat() and is_newconf() to
- * determine if any configuration files have changed. Optional config
- * files which do not exist have a 0 stored in the mtime field.
- */
- struct config_stat {
- struct config_stat *succ;
- char *fn; /* name of config file */
- time_t mtime; /* time of last mod */
- dev_t dev; /* device file resides on */
- ino_t ino; /* inode number for file */
- } *config_stat_list = NULL;
-
- /* define the attributes which may be in the config file */
- static struct attr_table conf_attributes[] = {
- { "auth_domains", t_string, NULL, (tup *)&auth_domains, 0 },
- { "auth_domain", t_string, NULL, (tup *)&auth_domains, 0 },
- { "auto_mkdir", t_boolean, NULL, (tup *)&auto_mkdir, 0 },
- { "auto_mkdir_mode", t_int, NULL, (tup *)&auto_mkdir_mode, 0 },
- { "config_file", t_string, NULL, (tup *)&config_file, 0 },
- { "console", t_string, NULL, (tup *)&cons_fn, 0 },
- { "copying_file", t_string, NULL, (tup *)©ing_file, 0 },
- { "date_field", t_string, NULL, (tup *)&date_field, 0 },
- { "delivery_mode", t_string, NULL, (tup *)&delivery_mode_string, 0 },
- { "director_file", t_string, NULL, (tup *)&director_file, 0 },
- { "domains", t_string, NULL, (tup *)&visible_domains, 0 },
- { "domain", t_string, NULL, (tup *)&visible_domains, 0 },
- { "visible_domains", t_string, NULL, (tup *)&visible_domains, 0 },
- { "visible_domain", t_string, NULL, (tup *)&visible_domains, 0 },
- { "error_copy_postmaster", t_boolean, NULL,
- (tup *)&error_copy_postmaster, 0 },
- { "flock_mailbox", t_boolean, NULL, (tup *)&flock_mailbox, 0 },
- { "fnlock_interval", t_int, NULL, (tup *)&fnlock_interval, 0 },
- { "fnlock_mode", t_int, NULL, (tup *)&fnlock_mode, 0 },
- { "fnlock_retries", t_int, NULL, (tup *)&fnlock_retries, 0 },
- { "from_field", t_string, NULL, (tup *)&from_field, 0 },
- { "grades", t_string, NULL, (tup *)&grades, 0 },
- { "hit_table_len", t_int, NULL, (tup *)&hit_table_len, 0 },
- { "host_lock_timeout", t_interval, NULL, (tup *)&host_lock_timeout, 0 },
- { "hostnames", t_string, NULL, (tup *)&hostnames, 0 },
- { "hostname", t_string, NULL, (tup *)&hostnames, 0 },
- { "lock_by_name", t_boolean, NULL, (tup *)&lock_by_name, 0 },
- { "lock_mode", t_int, NULL, (tup *)&lock_mode, 0 },
- { "log_mode", t_int, NULL, (tup *)&log_mode, 0 },
- { "logfile", t_string, NULL, (tup *)&log_fn, 0 },
- { "max_hop_count", t_int, NULL, (tup *)&max_hop_count, 0 },
- { "max_load_ave", t_double, NULL, (tup *)&max_load_ave, 0 },
- { "max_message_size", t_long, NULL, (tup *)&max_message_size, 0 },
- { "message_buf_size", t_int, NULL, (tup *)&message_bufsiz, 0 },
- { "message_id_field", t_string, NULL, (tup *)&message_id_field, 0 },
- { "message_log_mode", t_int, NULL, (tup *)&message_log_mode, 0 },
- { "method_dir", t_string, NULL, (tup *)&method_dir, 0 },
- { "more_hostnames", t_string, NULL, (tup *)&more_hostnames, 0 },
- { "gateway_names", t_string, NULL, (tup *)&more_hostnames, 0 },
- { "nobody", t_string, NULL, (tup *)&nobody, 0 },
- { "open_interval", t_int, NULL, (tup *)&open_interval, 0 },
- { "open_retries", t_int, NULL, (tup *)&open_retries, 0 },
- { "paniclog", t_string, NULL, (tup *)&panic_fn, 0 },
- { "postmaster_address", t_string, NULL, (tup *)&postmaster_address, 0 },
- { "postmaster", t_string, NULL, (tup *)&postmaster_address, 0 },
- { "primary_name", t_string, NULL, (tup *)&primary_name, 0 },
- { "qualify_file", t_string, NULL, (tup *)&qualify_file, 0 },
- { "queue_only", t_boolean, NULL, (tup *)&queue_only, 0 },
- { "received_field", t_string, NULL, (tup *)&received_field, 0 },
- { "require_configs", t_boolean, NULL, (tup *)&require_configs, 0 },
- { "retry_duration", t_interval, NULL, (tup *)&retry_duration, 0 },
- { "retry_file", t_string, NULL, (tup *)&retry_file, 0 },
- { "retry_interval", t_interval, NULL, (tup *)&retry_interval, 0 },
- { "return_path_field", t_string, NULL, (tup *)&return_path_field, 0 },
- { "router_file", t_string, NULL, (tup *)&router_file, 0 },
- { "second_config_file", t_string, NULL, (tup *)&second_config_file, 0 },
- { "sender_env_variable", t_string, NULL, (tup *)&sender_env_variable, 0 },
- { "smail", t_string, NULL, (tup *)&smail, 0 },
- { "smail_lib_dir", t_string, NULL, (tup *)&smail_lib_dir, 0 },
- { "smail_util_dir", t_string, NULL, (tup *)&smail_util_dir, 0 },
- { "smart_path", t_string, NULL, (tup *)&smart_path, 0 },
- { "smart_transport", t_string, NULL, (tup *)&smart_transport, 0 },
- { "smart_user", t_string, NULL, (tup *)&smart_user, 0 },
- { "smtp_banner", t_string, NULL, (tup *)&smtp_banner, 0 },
- { "smtp_debug", t_boolean, NULL, (tup *)&smtp_debug, 0 },
- { "smtp_accept_max", t_int, NULL, (tup *)&smtp_accept_max, 0 },
- { "smtp_accept_queue", t_int, NULL, (tup *)&smtp_accept_queue, 0 },
- { "smtp_receive_command_timeout", t_interval, NULL,
- (tup *)&smtp_receive_command_timeout, 0 },
- { "smtp_receive_message_timeout", t_interval, NULL,
- (tup *)&smtp_receive_message_timeout, 0 },
- { "spool_dirs", t_string, NULL, (tup *)&spool_dirs, 0 },
- { "spool_dir", t_string, NULL, (tup *)&spool_dir, 0 },
- { "spool_grade", t_char, NULL, (tup *)&spool_grade, 0 },
- { "spool_mode", t_int, NULL, (tup *)&spool_mode, 0 },
- { "switch_percent_and_bang", t_boolean, NULL,
- (tup *)&switch_percent_and_bang, 0 },
- { "transport_file", t_string, NULL, (tup *)&transport_file, 0 },
- { "trusted", t_string, NULL, (tup *)&trusted, 0 },
- { "trusted_users", t_string, NULL, (tup *)&trusted, 0 },
- { "trusted_user", t_string, NULL, (tup *)&trusted, 0 },
- { "trusted_groups", t_string, NULL, (tup *)&trusted_groups, 0 },
- { "trusted_group", t_string, NULL, (tup *)&trusted_groups, 0 },
- #ifdef GLOTZNET
- { "tzoffset", t_int, NULL, (tup *)&tzoffset, 0 },
- { "tznodst", t_boolean, NULL, (tup *)&tznodst, 0 },
- #endif /* GLOTZNET */
- { "uucp_name", t_string, NULL, (tup *)&uucp_name, 0 },
- { "version", t_infoproc, NULL, (tup *)version, 0 },
- { "visible_name", t_string, NULL, (tup *)&visible_name, 0 },
- };
- struct attr_table *end_conf_attributes = ENDTABLE(conf_attributes);
-
-
- /*
- * read_config_file - read a config file and fill in conf_attributes
- *
- * return an error message or NULL (if no error).
- */
- char *
- read_config_file(fn)
- char *fn; /* name of a config file */
- {
- char *entry; /* entry found by read_entry */
- FILE *f; /* input file */
- struct stat statbuf;
-
- if (fn == NULL || EQ(fn, "-")) {
- /* a name of `-' turns off use of the external file */
- return NULL;
- }
-
- f = fopen(fn, "r");
- if (f == NULL) {
- if (require_configs) {
- return xprintf("%s: %s", fn, strerrno());
- }
-
- add_config_stat(fn, (struct stat *)NULL);
- return NULL;
- }
-
- (void)fstat(fileno(f), &statbuf);
- add_config_stat(fn, &statbuf);
-
- /*
- * read all of the entries in the config file
- */
- while (entry = read_entry(f)) {
- char *error;
- struct attr_table *conf_attr;
- struct attribute *attr = parse_config(entry, &error);
-
- if (attr == NULL) {
- return xprintf("%s: parse error: %s", fn, error);
- }
- conf_attr = find_attribute(attr->name, conf_attributes,
- end_conf_attributes);
- if (conf_attr == NULL) {
- return xprintf("%s: unknown attribute: %s",
- fn, attr->name);
- }
- conf_attr->value = attr->value;
-
- if (conf_attr->type == t_boolean) {
- /* make sure boolean types are given as booleans */
- if (attr->value != on && attr->value != off) {
- return xprintf("%s: boolean attribute %s has non-boolean form",
- fn, attr->name);
- }
- } else {
- /* make sure non-boolean types aren't given as booleans */
- if ((attr->value == on &&
- conf_attr->type != t_proc) ||
- (attr->value == off &&
- conf_attr->type != t_string &&
- conf_attr->type != t_int &&
- conf_attr->type != t_long &&
- conf_attr->type != t_interval &&
- conf_attr->type != t_double &&
- conf_attr->type != t_proc))
- {
- return xprintf("%s: non-boolean attribute %s has boolean form",
- fn, attr->name);
- }
- }
-
- switch (conf_attr->type) {
- case t_string:
- if (attr->value == off) {
- conf_attr->uptr->v_string = NULL;
- } else {
- conf_attr->uptr->v_string = attr->value;
- }
- break;
-
- case t_boolean:
- conf_attr->uptr->v_boolean =
- (int)c_atol(attr->value, &error);
- break;
-
- case t_char:
- if (strlen(attr->value) != 1) {
- return xprintf("%s: bad character constant for attribute %s",
- fn, attr->name);
- }
- conf_attr->uptr->v_char = attr->value[0];
- break;
-
- case t_int:
- error = NULL;
- conf_attr->uptr->v_int = (int)c_atol(attr->value, &error);
-
- if (error) {
- return xprintf("%s: attribute %s: %s",
- fn, attr->name, error);
- }
- break;
-
- case t_long:
- error = NULL;
- conf_attr->uptr->v_long = c_atol(attr->value, &error);
-
- if (error) {
- return xprintf("%s: attribute %s: %s",
- fn, attr->name, error);
- }
- break;
-
- case t_interval:
- {
- long val;
-
- if ((val = ivaltol(attr->value)) < 0) {
- return xprintf(
- "%s: attribute %s: malformed interval value %s",
- fn, attr->name, attr->value);
- }
- conf_attr->uptr->v_long = val;
- }
- break;
-
- case t_double:
- {
- double val;
- char c; /* catch sscanf spill over */
-
- /* should be exactly one item set by sscanf */
- if (sscanf(attr->value, "%lf%c", &val, &c) != 1) {
- return xprintf(
- "%s: attribute %s: malformed floating number %s",
- fn, attr->name, attr->value);
- }
- conf_attr->uptr->v_double = val;
- }
- break;
-
- case t_proc:
- /* if (error = conf_attr->uptr->v_proc(attr)) { */
- if (error = (*((char *(*)())conf_attr->uptr))(attr)) {
- return xprintf("%s: %s", fn, error);
- }
- break;
-
- case t_infoproc:
- return xprintf("%s: %s: read-only attribute", fn, attr->name);
-
- default:
- return xprintf("%s: %s: unknown attribute type", fn, attr->name);
- }
- }
-
- return NULL;
- }
-
- /*
- * print_config_variable - write the value for a config variable on stdout
- */
- void
- print_config_variable(name)
- char *name;
- {
- struct attr_table *conf_attr;
- char *value;
-
- if (EQ(name, "help")) {
- print_config_help();
- return;
- }
- if (EQ(name, "all")) {
- print_config_all();
- return;
- }
-
- conf_attr = find_attribute(name, conf_attributes, end_conf_attributes);
-
- if (conf_attr == NULL && errfile) {
- (void) fprintf(errfile, "%s: unknown attribute: %s\n", program, name);
- return;
- }
- if (conf_attr == NULL) {
- return;
- }
- switch (conf_attr->type) {
- case t_string:
- if (conf_attr->uptr->v_string) {
- value = conf_attr->uptr->v_string;
- } else {
- value = "";
- }
- break;
-
- case t_boolean:
- if (conf_attr->uptr->v_boolean) {
- value = "true";
- } else {
- value = "false";
- }
- break;
-
- case t_char:
- {
- static char charv[2] = "x";
-
- charv[0] = conf_attr->uptr->v_char;
- value = charv;
- }
- break;
-
- case t_int:
- {
- static char intv[20];
-
- (void) sprintf(intv, "%d", conf_attr->uptr->v_int);
- value = intv;
- }
- break;
-
- case t_long:
- {
- static char longv[20];
-
- (void) sprintf(longv, "%ld", conf_attr->uptr->v_long);
- value = longv;
- }
- break;
-
- case t_interval:
- if ((value = ltoival(conf_attr->uptr->v_long)) == NULL) {
- static char v[20];
- sprintf(v, "%ld", conf_attr->uptr->v_long);
- value = v;
- }
- break;
-
- case t_double:
- {
- static char doublev[20];
-
- (void) sprintf(doublev, "%g", conf_attr->uptr->v_double);
- value = doublev;
- }
- break;
-
- case t_proc:
- if (errfile) {
- (void) fprintf(errfile, "%s: %s: cannot print proc attributes\n",
- program, name);
- }
- return;
-
- case t_infoproc:
- value = (*((char *(*)())conf_attr->uptr))();
- break;
-
- default:
- if (errfile) {
- (void) fprintf(errfile, "%s: %s: unknown type\n");
- }
- return;
- }
- if (debug) {
- (void) printf("%s=%s\n", name, value);
- } else {
- (void) printf("%s\n", value);
- }
- }
-
- /*
- * print_config_help - output a listing of all config attributes, with type
- */
- static void
- print_config_help()
- {
- register struct attr_table *t;
- register tup *last_uptr = NULL;
-
- for (t = conf_attributes; t < end_conf_attributes; t++) {
- register char *typename;
-
- if (t->uptr == last_uptr) {
- continue;
- }
- last_uptr = t->uptr;
- switch(t->type) {
- case t_string: typename = "string"; break;
- case t_boolean: typename = "boolean"; break;
- case t_char: typename = "char"; break;
- case t_int: typename = "int"; break;
- case t_long: typename = "long"; break;
- case t_interval:typename = "interval";break;
- case t_double: typename = "double"; break;
- case t_proc: typename = "special"; break;
- case t_infoproc:typename = "info"; break;
- default: typename = "unkown type"; break;
- }
- (void) printf("%s=%s\n", t->name, typename);
- }
- }
-
- /*
- * print_config_all - print all config file variables
- */
- static void
- print_config_all()
- {
- register struct attr_table *t;
- register tup *last_uptr = NULL;
- int save_debug = debug;
-
- debug = 1;
- for (t = conf_attributes; t < end_conf_attributes; t++) {
- if (t->uptr == last_uptr) {
- continue;
- }
- last_uptr = t->uptr;
- switch(t->type) {
- case t_string:
- case t_boolean:
- case t_char:
- case t_int:
- case t_long:
- case t_interval:
- case t_double:
- case t_infoproc:
- print_config_variable(t->name);
- break;
- default:
- (void) printf("%s: unknown type\n", t->name);
- break;
- }
- }
- debug = save_debug;
- }
-
-
- /*
- * read_standard_file - read (for example) a transport, director or router file
- *
- * given a template default structure, some information about that structure,
- * and an attr_table describing attributes, read a file of standard
- * attribute descriptions and return a list describing all of the entries
- * in that file.
- *
- * inputs:
- * f - open input file. File format must conform to what is
- * expected by read_entry and parse_entry in parse.c.
- * template - pointer to the template structure.
- * struct_size - size of template structure.
- * name_offset - offset to the name element in the template structure.
- * flags_offset - offset to flags element of structure.
- * succ_offset - offset to succ element of structure.
- * attr_table - table defining generic attributes.
- * end_attr_table- end of the attribute table
- *
- * driv_function - function to handle driver attributes for each entry.
- * Also, this function can check the validity of the
- * generic attributes in the passed structure. The
- * function should return NULL, or an error message.
- * It is called as:
- *
- * char *
- * f(s, d)
- * char *s; --- structure being defined
- * struct attribute *d; --- driver attributes
- *
- * If driv_function is NULL, no driver attributes are
- * allowed and no function is called.
- * head - pointer to a variable in which to store the head
- * of the generated structure list.
- *
- * output:
- * If an error occured, an error message will be returned.
- * Otherwise NULL will be returned and a pointer to the new
- * structure list will be stored at the location pointed to by
- * `head'.
- */
- char *
- read_standard_file(f, template, struct_size,
- name_offset, flags_offset, succ_offset,
- attr_table, end_attr_table,
- driv_function, head)
- FILE *f; /* input file */
- register char *template; /* template structure */
- int struct_size; /* size of template structure */
- int name_offset; /* name field offset in structure */
- int flags_offset; /* where to store boolean flags */
- int succ_offset; /* where to store succ pointer */
- struct attr_table *attr_table; /* start of attribute table */
- struct attr_table *end_attr_table; /* e.g., ENDTABLE(attr_table) */
- char *(*driv_function)(); /* function to handle driver attrs */
- char **head; /* output structure list */
- {
- char **link_ptr; /* pointer to last succ element */
- char *cur; /* current structure to define */
- char *s; /* text for current entry */
-
- /* start out with no structure list entries */
- link_ptr = head;
- *link_ptr = NULL;
-
- /*
- * scan through reading entries. For each entry allocate a
- * structure and fill it in. Also, link the new structure to the
- * previous structure.
- */
- while (s = read_entry(f)) {
- char *error;
- struct attribute *generic_attrs; /* generic attributes for entry */
- struct attribute *driver_attrs; /* driver attributes for entry */
- char *name; /* name of entry */
-
- /* create the new structure and forward link to it */
- *link_ptr = cur = xmalloc(struct_size);
- link_ptr = (char **)(cur + succ_offset);
-
- /* fill in the entry structure, starting with the template */
- (void) memcpy(cur, template, struct_size);
-
- /* get all of the attributes */
- name = parse_entry(s, &generic_attrs, &driver_attrs, &error);
- if (name == NULL) {
- return error;
- }
-
- /* fill in the name */
- *(char **)(cur + name_offset) = name;
-
- /*
- * fill in the generic attributes, calling attr_function for
- * attributes not in attr_table
- */
- error = fill_attributes(cur, generic_attrs,
- (long *)(cur + flags_offset),
- attr_table, end_attr_table);
- if (error) {
- return error;
- }
- if (driv_function) {
- error = (*driv_function)(cur, driver_attrs);
- if (error) {
- return error;
- }
- } else if (driver_attrs) {
- return xprintf("no driver attributes allowed in file");
- }
- }
-
- /* everything went okay */
- return NULL;
- }
-
-
- /*
- * fill_attributes - build a structure and fill in attributes
- *
- * Given a list of attributes extracted from one of the configuration
- * files and an array of known attributes, fill in a stucture to which
- * those attributes pertain.
- *
- * inputs:
- * sp - pointer to stucture that is to be filled in
- * attrs - list of given attributes
- * flags - pointer to long where boolean flags should be OR'd in
- * attr_table - table describing known attributes
- * end_attr_table- end of known attribies (i.e., ENDTABLE(attr_table))
- *
- * output:
- * returns either an error message, or NULL if everything went okay.
- */
- char *
- fill_attributes(sp, attrs, flags, attr_table, end_attr_table)
- char *sp;
- struct attribute *attrs;
- long *flags;
- struct attr_table *attr_table;
- struct attr_table *end_attr_table;
- {
- char *error;
-
- /* step through all of the attributes from the file entry */
- for (; attrs; attrs = attrs->succ) {
- register struct attr_table *t; /* table entry */
- register char *value = attrs->value;
-
- /* find the attribute in the list of known attributes */
- t = find_attribute(attrs->name, attr_table, end_attr_table);
- if (t == NULL) {
- /* didn't find the attribute */
- return xprintf("%s: unknown attribute", attrs->name);
- }
-
- /* what do with this attribute? */
- if (t->type == t_boolean) {
- /* make sure boolean types are given as booleans */
- if (attrs->value != on && attrs->value != off) {
- return xprintf("boolean attribute %s has non-boolean form",
- attrs->name);
- }
- } else {
- if ((attrs->value == on &&
- t->type != t_proc) ||
- (attrs->value == off &&
- t->type != t_string &&
- t->type != t_int &&
- t->type != t_long &&
- t->type != t_interval &&
- t->type != t_double &&
- t->type != t_proc))
- {
- return xprintf("non-boolean attribute %s has boolean form",
- attrs->name);
- }
- }
-
- /* fill in the attribute */
- switch (t->type) {
- case t_string:
- if (value == off) {
- *(char **)(sp + t->offset) = NULL;
- } else {
- *(char **)(sp + t->offset) = value;
- }
- break;
-
- case t_boolean:
- if (value == on) {
- *flags |= t->offset;
- } else {
- *flags &= ~t->offset;
- }
- break;
-
- case t_char:
- if (strlen(attrs->value) != 1) {
- return xprintf("bad character constant for attribute %s",
- attrs->name);
- }
- *(sp + t->offset) = value[0];
- break;
-
- case t_int:
- error = NULL;
- *(int *)(sp + t->offset) = (int)c_atol(value, &error);
-
- if (error) {
- return xprintf("attribute %s: %s", attrs->name, error);
- }
- break;
-
- case t_long:
- error = NULL;
- *(long *)(sp + t->offset) = c_atol(value, &error);
-
- if (error) {
- return xprintf("attribute %s: %s", attrs->name, error);
- }
- break;
-
- case t_interval:
- {
- long val;
-
- if ((val = ivaltol(value)) < 0) {
- return xprintf("attribute %s: malformed interval value %s",
- attrs->name, value);
- }
- *(long *)(sp + t->offset) = val;
- }
-
- case t_double:
- {
- double val;
- char c; /* catch sscanf spill over */
-
- /* should be exactly one item set by sscanf */
- if (sscanf(value, "%lf%c", &val, &c) != 1) {
- return xprintf(
- "attribute %s: malformed floating number %s",
- attrs->name, value);
- }
- *(double *)(sp + t->offset) = val;
- }
- break;
-
- case t_proc:
- /* if (error = t->uptr->v_proc(sp, attrs)) { */
- if (error = (*((char *(*)())t->uptr))(sp, attrs)) {
- return error;
- }
- }
- }
-
- return NULL;
- }
-
- /*
- * find_attribute - find an attribute within an attribute table
- */
- struct attr_table *
- find_attribute(name, table, end)
- register char *name; /* name to search for */
- register struct attr_table *table; /* table to search in */
- register struct attr_table *end; /* end of table */
- {
- while (table < end) {
- if (EQ(name, table->name)) {
- return table;
- }
- table++;
- }
- return NULL;
- }
-
-
- /*
- * add_config_stat - add a new config file to config_stat_list
- *
- * Pass a filename plus a pointer to a stat structure or NULL.
- */
- void
- add_config_stat(fn, statp)
- char *fn; /* name of file */
- struct stat *statp; /* stat of the file, or NULL */
- {
- struct config_stat *new = (struct config_stat *)xmalloc(sizeof(*new));
-
- new->fn = COPY_STRING(fn);
- if (statp) {
- new->mtime = statp->st_mtime;
- new->dev = statp->st_dev;
- new->ino = statp->st_ino;
- } else {
- new->mtime = (time_t)0;
- }
- new->succ = config_stat_list;
- config_stat_list = new;
- }
-
- /*
- * is_newconf - check if we have a new set of configuration files
- *
- * returns TRUE if a configuration fie has changed, FALSE otherwise
- */
- int
- is_newconf()
- {
- struct stat statbuf;
- struct config_stat *csp;
-
- for (csp = config_stat_list; csp; csp = csp->succ) {
- if (stat(csp->fn, &statbuf) < 0) {
- if (csp->mtime != (time_t)0) {
- /* file no longer exists */
- return TRUE;
- }
- } else {
- if (csp->mtime == (time_t)0) {
- /* file now exists */
- return TRUE;
- }
- if (csp->mtime != statbuf.st_mtime ||
- csp->dev != statbuf.st_dev ||
- csp->ino != statbuf.st_ino)
- {
- /* existing file has changed */
- return TRUE;
- }
- }
- }
-
- /* nothing has changed */
- return FALSE;
- }
-
- /*
- * make_lib_fn - build a filename relative to the smail lib directory
- *
- * If the filename begins with '/' or is "-" return it unmodified.
- * Return NULL if smail_lib_dir is undefined, or if the given
- * filename is NULL.
- */
- char *
- make_lib_fn(fn)
- char *fn; /* filename to expand */
- {
- if (fn == NULL) {
- return NULL;
- }
- if (fn[0] == '/' || (fn[0] == '-' && fn[1] == '\0')) {
- return fn;
- }
- if (smail_lib_dir == NULL) {
- return NULL;
- }
- #ifdef GLOTZNET
- return xprintf("%s/%s/%s", smail_lib_dir, glotzhost, fn);
- #else /* GLOTZNET */
- return xprintf("%s/%s", smail_lib_dir, fn);
- #endif /* GLOTZNET */
- }
-
-
- #ifdef STANDALONE
-
- #include "varargs.h"
-
- struct transport *transports;
- struct director *directors;
- struct router *routers;
-
- /*
- * find_direct_driver - given a driver's name, return the driver structure
- *
- * return NULL if driver does not exist.
- */
- struct direct_driver *
- find_direct_driver(name)
- register char *name; /* search key */
- {
- #ifdef notyet
- register struct direct_driver *ddp; /* pointer to table of drivers */
-
- for (ddp = direct_drivers; ddp->name; ddp++) {
- if (EQ(ddp->name, name)) {
- return ddp; /* found the driver */
- }
- }
-
- return NULL; /* driver not found */
- #else /* notyet */
- static struct direct_driver dd = {
- NULL, 1, NULL, NULL, NULL, NULL,
- };
-
- return ⅆ
- #endif /* notyet */
- }
-
- /*
- * find_transport_driver - given a driver's name, return the driver structure
- *
- * return NULL if driver does not exist.
- */
- struct transport_driver *
- find_transport_driver(name)
- register char *name; /* search key */
- {
- #ifdef notyet
- register struct transport_driver *tdp; /* pointer to table of drivers */
-
- for (tdp = transport_drivers; tdp->name; tdp++) {
- if (EQ(tdp->name, name)) {
- return tdp; /* found the driver */
- }
- }
-
- return NULL; /* driver not found */
- #else /* notyet */
- static struct transport_driver td = {
- NULL, 1, NULL, NULL, NULL, NULL,
- };
- return &td;
- #endif /* notyet */
- }
-
- /*
- * find_route_driver - given a driver's name, return the driver structure
- *
- * return NULL if driver does not exist.
- */
- struct route_driver *
- find_route_driver(name)
- register char *name; /* search key */
- {
- #ifdef notyet
- register struct route_driver *rdp; /* pointer to table of drivers */
-
- for (rdp = route_drivers; rdp->name; rdp++) {
- if (EQ(rdp->name, name)) {
- return rdp; /* found the driver */
- }
- }
-
- return NULL; /* driver not found */
- #else /* notyet */
- static struct route_driver rd = {
- NULL, 1, NULL, NULL, NULL, NULL,
- };
- return &rd;
- #endif /* notyet */
- }
-
- /*VARARGS2*/
- void
- panic(exitcode, fmt, va_alist)
- int exitcode; /* call exit(exitcode) */
- char *fmt; /* printf(3) format */
- va_dcl /* arguments for printf */
- {
- va_list ap;
-
- va_start(ap);
- (void)fprintf(stderr, "PANIC(%s): ", exitcode);
- (void)vfprintf(stderr, fmt, ap);
- putc('\n', stderr); /* fatal messages not \n terminated */
- va_end(ap);
-
- return_to_sender = TRUE;
- exit(exitcode);
- }
-
- /*VARARGS2*/
- void
- write_log(log, fmt, va_alist)
- int log; /* TRUE if to write global log file */
- char *fmt; /* printf(3) format */
- va_dcl /* arguments for printf */
- {
- va_list ap;
-
- va_start(ap);
- (void)fprintf(stderr, log? "PUBLIC: ": "PRIVATE: ");
- (void)vfprintf(stderr, fmt, ap);
- putc('\n', stderr);
- va_end(ap);
- }
-
- void
- main(argc, argv)
- int argc; /* count of arguments */
- char *argv[]; /* vector of arguments */
- {
- char *error;
-
- if (argc != 2) {
- (void) fprintf(stderr, "Usage: %s config-file", argv[0]);
- /*NOTREACHED*/
- }
-
- config_file = argv[1];
- if ((error = read_config_file(config_file, CONFIG_PRIMARY)) ||
- (second_config_file &&
- error = read_config_file(second_config_file, CONFIG_SECONDARY))
- (error = read_transport_file()) ||
- (error = read_router_file()) ||
- (error = read_director_file()) ||
- (error = read_qualify_file()) ||
- (error = read_retry_file()))
- {
- (void) fprintf(stderr, "%s: %s\n", argv[0], error);
- }
- }
- #endif /* STANDALONE */
-